#!/usr/bin/env python
# coding=UTF-8

# gvpnc v. 1.02
# Copyright © 2007, Super Mike

# A GUI for the vpnc command (distributed separately)

# You may change and re-release as commercial and customized versions per the license. See artistic license.


# the imports below I just pulled from boilerplate from redhat control panels
# and then added others as I received errors
import sys
import os
from subprocess import PIPE, Popen, call
import string
import pygtk
pygtk.require('2.0')
import gtk
import gobject
import pango
import gtk.gdk
import gtk.glade

# assign our globals
global txtResultFont
global window

CONFIGDIR = os.path.expanduser("~/.config/gvpnc")
CONFIGFILE = os.path.join(CONFIGDIR, "default.conf")

def LoadConfig(filename=None):
	global CONFIGFILE
	if filename:
		if not os.path.isabs(filename):
			filename = os.path.join(CONFIGDIR, filename)
		CONFIGFILE = filename

	SetWidgetText("profile_name", os.path.basename(CONFIGFILE))
	gateway = group = group_pwd = username = password = None
	try:
		lines = open(CONFIGFILE,"r").readlines()
		for line in lines:
			if line.startswith("IPSec gateway"):
				gateway = line.split()[2]
			elif line.startswith("IPSec ID"):
				group = line.split()[2]
			elif line.startswith("IPSec secret"):
				group_pwd = line.split()[2]
			elif line.startswith("Xauth username"):
				username = line.split()[2]
			elif line.startswith("Xauth password"):
				password = line.split()[2]
	except (IOError):
		pass

	SetWidgetText('run_server',gateway)
	Widget('run_password').grab_focus()
	SetWidgetText('run_groupname',group)
	SetWidgetText('run_grouppassword',group_pwd)
	SetWidgetText('run_username',username)
	SetWidgetText('run_password',password)


# our signal handling (mostly in menu order)
def on_Run(*args):
	Widget('filechooserbutton1').set_current_folder(CONFIGDIR)
	LoadConfig()
	ShowWindow('run_command')

def on_NewConfig(*args):
	(filechooser, ) = args
	config = filechooser.get_filename()
	if config:
		LoadConfig(config)

def on_Quit(*args):
	QuitAll()

def on_About(*args):
	MessageBox("\n\n\tGnome Cisco VPN Connector GUI (gvpnc)\t\t\n\tCopyright © 2007, Super Mike, v. 1.02\t\t\n\n\tThe component vpnc is required and\n\tis not shippped with this GUI. As of\n\tthis build, vpnc copyrights were listed\n\tas: Copyright (C) 2002-2004 Geoffrey\n\tKeating, Maurice Massar. Without their\n\tefforts, gvpnc could not be possible.\n\t\t\n\n\tThis GUI is distributed on the Artistic License.\n\t\t")

# and now the ancillary signals

def on_RunNow(*args):
	sServer = GetWidgetText('run_server')
	sGroup = GetWidgetText('run_groupname')
	sGroupPass = GetWidgetText('run_grouppassword')
	sUser = GetWidgetText('run_username')
	sPass = GetWidgetText('run_password')
	sConf = GetWidgetText('profile_name')
	config = file(os.path.join(CONFIGDIR, sConf), "w+")
	config.write("# AUTOGENERATED BY gvpnc\n")
	config.write("IPSec gateway "+sServer+"\n")
	config.write("IPSec ID "+sGroup+"\n")
	config.write("IPSec secret "+sGroupPass+"\n")
	config.write("Xauth username "+sUser+"\n")
	config.write("Xauth password "+sPass+"\n")
	config.close()
	HideWindow('run_command')
	Refresh()

	if call(["which","gksudo"]):
		ErrorBox("Cannot find gksudo on your path.  Please install gksudo before running gvpnc.")
		return

	if call(["which","vpnc"]):
		ErrorBox("Cannot find vpnc on your path.  Please install vpnc before running gvpnc.")
		return
		
	proc = Popen(["gksudo", "vpnc", CONFIGFILE], stderr=PIPE, stdout=PIPE)
	Result, Error = proc.communicate()

	if Error:
		Status('Server: ' + sServer + ' Failed to Connect.')
		SetWidgetText('txtResult', Error)
	else:
		Status('Server: ' + sServer + ' CONNECTED')
		SetWidgetText('txtResult', Result)

def on_Stop(*args):
	sServer = GetWidgetText('run_server')
	proc = Popen(["gksudo", "vpnc-disconnect"], stderr=PIPE, stdout=PIPE)
	Result, Error = proc.communicate()

	if Error:
		Status("Error.")
		SetWidgetText('txtResult', Error)
	else:
		Status('Server: ' + sServer + ' Disconnected')
		SetWidgetText('txtResult', Result)

def on_RunCancel(*args):
	HideWindow('run_command')

def on_AboutClose(*args):
	HideWindow('about')

# and now our functions to make life easier

def GetWidgetText(sName):
	sResult = ''
	try: # for ordinary text fields
		sResult = Widget(sName).get_text()
	except:
		try: # for scrolling textboxes
			c1 = Widget(sName).get_buffer().get_start_iter()
			c2 = Widget(sName).get_buffer().get_end_iter()
			sResult = Widget(sName).get_buffer().get_slice(c1,c2,True)
		except:
			pass
	if (sResult == ''):
		try: # for scrolling textboxes
			c1 = Widget(sName).get_buffer().get_start_iter()
			c2 = Widget(sName).get_buffer().get_end_iter()
			sResult = Widget(sName).get_buffer().get_slice(c1,c2,True)
		except:
			sResult = ''
	return sResult

def SetWidgetText(sName, sText):
	if (sText == ''):
		try:
			aReset = string.split('\n', "\n")
			Widget(sName).set_popdown_strings(aReset)
		except:
			pass
	try:
		Widget(sName).get_buffer().set_text(sText)
	except:
		try:
			Widget(sName).set_text(sText)
		except:
			return

def Widget(sName):
	return MyWindows.get_widget(sName)

def ShowWindow(thewindow):
    Widget(thewindow).show()

def HideWindow(thewindow):
    Widget(thewindow).hide()

def Destroy(thewindow):
    Widget(thewindow).destroy()

def Status(sMsg):
	Widget('statusbar1').pop(0)
	Widget('statusbar1').push(0,sMsg)

def MessageBox(sMsg):
	global window
	dialog = gtk.MessageDialog(
		window,
		gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
		gtk.MESSAGE_INFO,
		gtk.BUTTONS_OK,
		sMsg
	)
	dialog.run()
	dialog.destroy()

def ErrorBox(sMsg):
	global window
	dialog = gtk.MessageDialog(
		window,
		gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
		gtk.MESSAGE_WARNING,
		gtk.BUTTONS_OK,
		sMsg
	)
	dialog.run()
	dialog.destroy()

def QuestionYesNoBox(sMsg):
	global window
	dialog = gtk.MessageDialog(
		window,
		gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
		gtk.MESSAGE_QUESTION,
		gtk.BUTTONS_YES_NO,
		sMsg
	)
	response = dialog.run()
	dialog.destroy()
	return response

def QuestionOKCancelBox(sMsg):
	global window
	dialog = gtk.MessageDialog(
		window,
		gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
		gtk.MESSAGE_QUESTION,
		gtk.BUTTONS_OK_CANCEL,
		sMsg
	)
	response = dialog.run()
	dialog.destroy()
	return response

def gtk_main_quit(*args):
    gtk.main_quit()

def Refresh():
    while gtk.events_pending():
        gtk.main_iteration(False)

def QuitAll():
	Destroy('main')
	gtk.main_quit()

PROGNAME = 'GVPNC'

# let the glade file exist in multiple possible locations
gvpnc_bin_path = os.path.join(os.path.abspath(os.path.split(sys.argv[0])[0]), "gvpnc.glade")
for path in [gvpnc_bin_path, "/usr/share/gvpnc/gvpnc.glade", "/usr/local/share/gvpnc/gvpnc.glade"]:
	if os.path.exists(path):
		gvpnc_glade_file = path
		break

# load our Glade2 file with the GUI
MyWindows = gtk.glade.XML(gvpnc_glade_file,None,domain=PROGNAME)

# g var initizialization
window = None

# change font on the main text field
Widget('txtResult').modify_font(pango.FontDescription("Luxi Mono 8"))

# connect our signals to our glade file object
MyWindows.signal_autoconnect(locals())

# make sure user configuration directory exists
os.umask(066)  #make sure only owner can access any files we create
if not os.path.exists(CONFIGDIR):
	os.makedirs(CONFIGDIR)

# show our main window and go into main loop
ShowWindow('main')
Widget('statusbar1').grab_focus()
gtk.main()
